import java.util.Vector;

public class Analizador_Lexico {

	private int Estados = 12;
	private int Caracteres = 19;
	private int FinalState = Estados - 1;
	private int estadoActual;

	private char charActual;
	private String token = "";

	private CodeManager CodeM = new CodeManager();
	private Matriz Pasajes = new Matriz(Estados, Caracteres);
	private SimbolTable TablaSimbolos;

	private Vector<Error> Errors;
	private Vector<String> Tokens;

	public Analizador_Lexico() {
		cargarMatrizPasajes();
	}

	public void setToken(String t) {
		token = t;
	}

	public void devolverCaracter() {
		CodeM.backCursor();
	}

	public int getActualLine() {
		return CodeM.getLineaActual();
	}

	public Vector<Error> getErrors() {
		return Errors;
	}

	public Vector<String> getTokens() {
		return Tokens;
	}

	public Vector<String> getSimbolTable() {
		return TablaSimbolos.getSimbolos();
	}

	public void addSimbol(String id, String token) {
		TablaSimbolos.insertToken(id, token);
	}

	public void addError(String token, String id) {
		Error error = new Error(getActualLine(), token, id);
		Errors.add(error);
	}

	public void addNewToken(String token) {
		Tokens.add(token);
	}

	private void cargarMatrizPasajes() {
		Proceso0 P0 = new Proceso0();
		Proceso1 P1 = new Proceso1();
		Proceso2 P2 = new Proceso2();
		Proceso3 P3 = new Proceso3();
		Proceso4 P4 = new Proceso4();
		Proceso5 P5 = new Proceso5();
		Proceso6 P6 = new Proceso6();
		Proceso7 P7 = new Proceso7();
		Proceso9 P9 = new Proceso9();
		Proceso10 P10 = new Proceso10();
		Proceso11 P11 = new Proceso11();
		Proceso12 P12 = new Proceso12();
		ProcesoE1 PE1 = new ProcesoE1();
		ProcesoE2 PE2 = new ProcesoE2();
		ProcesoE3 PE3 = new ProcesoE3();
		ProcesoW PW = new ProcesoW();

		/*
		 * REFERENCIA DE LAS COLUMNAS EN LA MATRIZ 0:LETRA [a..z,A..Z] 1:DIGITO
		 * [0..9] 2:[+] 3:[-] 4:[*] 5:[/] 6:[>] 7:[<] 8:[=] 9:[!] 10:[{] 11:[}]
		 * 12:[(] 13:[)] 14:[,] 15:[;] 16:[\n,\t,\r] 17:OTRO CARACTER 18:[$]
		 */
		Pasajes.set_elem(new Nodo_matriz(1, P1), 0, 0);
		Pasajes.set_elem(new Nodo_matriz(2, P1), 0, 1);
		Pasajes.set_elem(new Nodo_matriz(9, P1), 0, 2);
		Pasajes.set_elem(new Nodo_matriz(10, P1), 0, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 4);
		Pasajes.set_elem(new Nodo_matriz(3, P1), 0, 5);
		Pasajes.set_elem(new Nodo_matriz(6, P1), 0, 6);
		Pasajes.set_elem(new Nodo_matriz(6, P1), 0, 7);
		Pasajes.set_elem(new Nodo_matriz(8, P1), 0, 8);
		Pasajes.set_elem(new Nodo_matriz(7, P1), 0, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P2), 0, 15);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 0, 16);
		Pasajes.set_elem(new Nodo_matriz(0, PE3), 0, 17);
		Pasajes.set_elem(new Nodo_matriz(11, PW), 0, 18);

		Pasajes.set_elem(new Nodo_matriz(1, P1), 1, 0);
		Pasajes.set_elem(new Nodo_matriz(1, P1), 1, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P3), 1, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 0);
		Pasajes.set_elem(new Nodo_matriz(2, P1), 2, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P7), 2, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 0);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 3);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 3, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P6), 3, 18);

		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 0);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 1);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 2);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 3);
		Pasajes.set_elem(new Nodo_matriz(5, P0), 4, 4);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 5);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 6);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 7);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 8);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 9);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 10);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 11);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 12);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 13);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 14);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 15);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 16);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 4, 17);
		Pasajes.set_elem(new Nodo_matriz(11, PE1), 4, 18);

		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 0);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 1);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 2);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 3);
		Pasajes.set_elem(new Nodo_matriz(5, P0), 5, 4);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 5, 5);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 6);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 7);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 8);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 9);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 10);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 11);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 12);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 13);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 14);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 15);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 16);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 17);
		Pasajes.set_elem(new Nodo_matriz(4, P0), 5, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 0);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P4), 6, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P5), 6, 18);

		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 0);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 1);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 2);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 3);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 4);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 5);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 6);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P4), 7, 8);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 9);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 10);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 11);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 12);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 13);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 14);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 15);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 16);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 17);
		Pasajes.set_elem(new Nodo_matriz(11, PE2), 7, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 0);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P4), 8, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P9), 8, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 0);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P10), 9, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P11), 9, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 9, 18);

		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 0);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 1);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 2);
		Pasajes.set_elem(new Nodo_matriz(11, P10), 10, 3);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 4);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 5);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 6);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 7);
		Pasajes.set_elem(new Nodo_matriz(11, P11), 10, 8);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 9);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 10);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 11);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 12);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 13);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 14);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 15);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 16);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 17);
		Pasajes.set_elem(new Nodo_matriz(11, P12), 10, 18);
		
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 0);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 1);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 2);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 3);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 4);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 5);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 6);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 7);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 8);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 9);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 10);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 11);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 12);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 13);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 14);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 15);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 16);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 17);
		Pasajes.set_elem(new Nodo_matriz(0, P0), 11, 18);
	}

	/* DADO UN CARACTER OBTENGO EL NUMERO DE LA COLUMNA ASOCIADO */
	public int getColumna(char ch) {
		if (ch == '+')
			return 2;
		if (ch == '-')
			return 3;
		if (ch == '*')
			return 4;
		if (ch == '/')
			return 5;
		if (ch == '>')
			return 6;
		if (ch == '<')
			return 7;
		if (ch == '=')
			return 8;
		if (ch == '!')
			return 9;
		if (ch == '{')
			return 10;
		if (ch == '}')
			return 11;
		if (ch == '(')
			return 12;
		if (ch == ')')
			return 13;
		if (ch == ',')
			return 14;
		if (ch == ';')
			return 15;
		if (ch == '$')
			return 18;
		if ((ch == '\n') || (ch == '\t') || (ch == ' '))
			return 16;
		if ((ch >= 'a') && (ch <= 'z'))
			return 0;
		if ((ch >= 'A') && (ch <= 'Z'))
			return 0;
		if ((ch >= '0') && (ch <= '9'))
			return 1;
		return 17;
	}

	public void AnalizarCodigo(String Code) {
		Errors = new Vector();
		Tokens = new Vector();
		TablaSimbolos = new SimbolTable();
		CodeM.LoadFromText(Code);
		estadoActual = 0; // ME UBICO EN EL PRIMER ESTADO
		charActual = ' ';
		while (CodeM.getPosActual() < CodeM.getContent().length()) {
			token = "";
			while (estadoActual != FinalState) {
				charActual = CodeM.nextChar();
				Nodo_matriz Nodo = (Nodo_matriz) Pasajes.get_elem(estadoActual,
						getColumna(charActual));
				Nodo.getProceso().ejecutar(token, charActual, this);
				estadoActual = Nodo.getProximo();
			}
			estadoActual = 0;
		}
	}
}
